package it.webrules.deploymanager.core.dy.deploy;

import it.webrules.deploymanager.core.config.ConfigurationService;
import it.webrules.deploymanager.core.dy.deploy.tomcat.TomcatConnection;
import it.webrules.deploymanager.core.hook.HandleHook;
import it.webrules.xsd.dmc.config.v1.GeneralConfig;
import it.webrules.xsd.dmc.config.v1.Hook;
import it.webrules.xsd.dmc.config.v1.WebappConfig.Deploys;
import it.webrules.xsd.dmc.config.v1.WebappConfig.Deploys.Tomcat;

import java.io.BufferedInputStream;
import java.io.InputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DeployService {

	private static final int ONESEC_IN_MS = 1000;

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	private final ConfigurationService configurationService;

	public DeployService(ConfigurationService configurationService) {
		this.configurationService = configurationService;
	}

	/**
	 * Check if all server are available
	 * @throws DeployException if any system is not available
	 */
	public void checkSystemReady() throws AvailableServerException {

		int error = 0;
		StringBuilder errors = new StringBuilder();

		Deploys deploys = configurationService.getDeploysElement();
		GeneralConfig generalConfig = configurationService.getGeneralConfig();

		for (Tomcat tomcat : deploys.getTomcat()) {
			logger.info("Check availability of {} ...", tomcat.getName());
			error += new TomcatConnection(tomcat, deploys, generalConfig).isAvailability(errors);
		}

		if (error > 0) {
			logger.error(errors.toString());
			throw new AvailableServerException("Found " + error + " error cheking availability of server!");
		}

	}

	/**
	 * 
	 * Deploy the artifact on servers, one by one.
	 * 
	 * @param artifact the war file
	 * @throws DeployException on any error
	 */
	public void deploy(InputStream artifact) throws DeployException {

		if (artifact == null)
			throw new DeployException("Can't deploy null artifact!");

		if (!artifact.markSupported())
			artifact = new BufferedInputStream(artifact);

		artifact.mark(Integer.MAX_VALUE);

		GeneralConfig generalConfig = configurationService.getGeneralConfig();
		Deploys deploys = configurationService.getDeploysElement();

		HandleHook handleHook = new HandleHook();

		Hook beforeHook = deploys.getBefore();
		if (beforeHook != null)
			handleHook.manageHook(generalConfig, null, beforeHook);

		for (Tomcat tomcat : deploys.getTomcat()) {

			try {

				logger.info("Deploy on {}, waiting {} seconds...", tomcat.getName(), deploys.getPausebetweendeploy());

				try {
					int millis = deploys.getPausebetweendeploy() * ONESEC_IN_MS;
					Thread.sleep(millis);
				} catch (Exception e) {
					// TODO migliorare questo log
					logger.error("Wait errorDeploy on {} ...", tomcat.getName());
				}

				artifact.reset();
				new TomcatConnection(tomcat, deploys, generalConfig, artifact).deploy();

			} catch (Exception e) {
				// very remote error
				throw new DeployException("Error deploying artifact on tomcat (" + tomcat.getName() + ") ", e);
			}
		}

		Hook afterHook = deploys.getAfter();
		if (afterHook != null)
			handleHook.manageHook(generalConfig, null, afterHook);

	}

}
